<?php

namespace App\Service\College;

use App\Jobs\College\AutoCloseExam;
use App\Jobs\College\FinishTrainingOrderJob;
use App\Library\Rms\RmsShopApi;
use App\Models\Appraise\AppraiseModel;
use App\Models\College\CollegeTrainingOrderLogModel;
use App\Models\College\CollegeTrainingOrderModel;
use App\Models\College\CollegeTrainingOrderPlanUserModel;
use App\Models\College\CollegeTrainingOrderUserModel;
use App\Models\College\CollegeTrainingPlanModel;
use App\Models\Common\ResourcesModel;
use App\Models\Cruise\CruiseOrderModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopOrderTagsMappingModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\System\SystemNotifyCenterModel;
use App\Service\BaseService;
use App\Service\Cruise\Mission\CollegeInputService;
use App\Service\OpenShop\Feishu\QualificationImageService;
use App\Service\OpenShop\Feishu\ShopTagsService;
use App\Service\OpenShop\User\RmsUserService;
use App\Service\System\SystemNotifyService;
use App\Service\WorkOrder\Appraise\NotifyService;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\DB;

class CollegeTrainingOrderService extends BaseService
{
    private ?CollegeTrainingOrderModel $collegeTrainingOrderModel;

    public function __construct(?int $id)
    {
        if ($id) {
            $this->collegeTrainingOrderModel = CollegeTrainingOrderModel::query()->find($id);
            if (!$this->collegeTrainingOrderModel) {
                self::throwErr("不存在的培训订单id: {$id}");
            }
        }
    }

    /**
     * 商学院确认培训单
     * @return void
     */
    public function confirm(int $currentUid, int $campus, int $planId, int $teacherShopId, array $userIds): void
    {
        if (!in_array($this->collegeTrainingOrderModel->status,
            [CollegeTrainingOrderModel::STATUS_COLLEGE_CONFIRM, CollegeTrainingOrderModel::STATUS_MERCHANT_CONFIRM])) {
            self::throwErr("当前状态错误");
        }

        if ($this->collegeTrainingOrderModel->status == CollegeTrainingOrderModel::STATUS_COLLEGE_CONFIRM) {
            if ($this->collegeTrainingOrderModel->userRel->count() == 0) {
                self::throwErr("未添加『确认参训人员』无法确认");
            }
        }

        if ($this->collegeTrainingOrderModel->status == CollegeTrainingOrderModel::STATUS_MERCHANT_CONFIRM) {
            if ($this->collegeTrainingOrderModel->userRel->count() == 0 && !$userIds) {
                self::throwErr("未添加『确认参训人员』无法确认");
            }
        }

        // 校验campus&planId
        if (!CollegeTrainingPlanModel::query()->where('campus', $campus)->where('id', $planId)->count()) {
            self::throwErr("无法找到校区下的该培训计划");
        }

        DB::beginTransaction();

        if ($this->collegeTrainingOrderModel->status == CollegeTrainingOrderModel::STATUS_MERCHANT_CONFIRM) {

            if ($this->collegeTrainingOrderModel->userRel->whereIn('userId', $userIds)->count()) {
                self::throwErr("添加人员重复");
            }

            foreach ($userIds as $userId) {
                CollegeTrainingOrderUserModel::init($userId, $this->collegeTrainingOrderModel->id);
            }

            CollegeTrainingOrderPlanUserModel::init($userIds, $this->collegeTrainingOrderModel->id);
            $this->collegeTrainingOrderModel->planNum = count($userIds);
        }

        $this->collegeTrainingOrderModel->planId              = $planId;
        $this->collegeTrainingOrderModel->teacherShopId       = $teacherShopId;
        $this->collegeTrainingOrderModel->status              = CollegeTrainingOrderModel::STATUS_ING;
        $this->collegeTrainingOrderModel->actualNum           = $this->collegeTrainingOrderModel->load('userRel')->userRel->count();
        $this->collegeTrainingOrderModel->merchantConfirmTime = time();
        $this->collegeTrainingOrderModel->save();

        CollegeExamService::initExam($this->collegeTrainingOrderModel);

        //添加日志
        CollegeTrainingOrderLogModel::add($this->collegeTrainingOrderModel->id, '商学院确认培训计划', $currentUid);

        DB::commit();

        // 工服标签更新
        (new ShopTagsService('', $this->collegeTrainingOrderModel->studentShopId))->updateWorkClothes();

        // 商学院确认培训单 删除 商学院待培训 标签
        (new ShopTagsService('', $this->collegeTrainingOrderModel->studentShopId))->delSchoolTag();

    }

    /**
     * 关闭培训订单
     * @return void
     */
    public function close(int $currentUid): void
    {
        if ($this->collegeTrainingOrderModel->status == CollegeTrainingOrderModel::STATUS_FINISH) {
            self::throwErr("该订单已完成，无法操作");
        }

        if ($this->collegeTrainingOrderModel->status == CollegeTrainingOrderModel::STATUS_CLOSE) {
            self::throwErr("该订单已关闭，无法操作");
        }

        DB::beginTransaction();

        $this->collegeTrainingOrderModel->status = CollegeTrainingOrderModel::STATUS_CLOSE;
        $this->collegeTrainingOrderModel->save();

        CollegeTrainingOrderLogModel::add($this->collegeTrainingOrderModel->id, '关闭订单', $currentUid);


//        $this->collegeTrainingOrderModel->userRel->each(function ($item) {
//
//            // 没答完题的关了
//            if ($item->examResult == CollegeTrainingOrderUserModel::RESULT_INIT) {
//                $item->examResult = CollegeTrainingOrderUserModel::RESULT_FAIL;
//                $item->save();
//            }
//        });

//        dd($this->collegeTrainingOrderModel);

        DB::commit();

        // 工服标签更新
        (new ShopTagsService('', $this->collegeTrainingOrderModel->studentShopId))->updateWorkClothes();

        // 关闭培训订单后 删除 商学院培训 标签
        (new ShopTagsService('', $this->collegeTrainingOrderModel->studentShopId))->delSchoolTag();

        dispatch((new FinishTrainingOrderJob($this->collegeTrainingOrderModel->id)));
    }

    /**
     * 实操上传
     * @param array $practiceTrainingUrls
     * @param array $failLetterUrls
     * @param array $users
     * @param int $currentUid
     * @param string $portrait
     * @return void
     * @throws GuzzleException
     */
    public function upload(array $practiceTrainingUrls, array $failLetterUrls, array $users, int $currentUid, string $portrait): void
    {
        if ($this->collegeTrainingOrderModel->status != CollegeTrainingOrderModel::STATUS_WAIT_UPLOAD) {
            self::throwErr("当前状态错误");
        }

        $users = collect($users)->keyBy('userId');

        DB::beginTransaction();

        if ($practiceTrainingUrls) {
            ResourcesModel::moduleBusinessSingleResourcesUpdate(
                ResourcesModel::MODULE_TYPE_COLLEGE,
                ResourcesModel::BUSINESS_COLLEGE_COURSES,
                'practiceTraining',
                $this->collegeTrainingOrderModel->id,
                $practiceTrainingUrls
            );
        }

        if ($failLetterUrls) {
            ResourcesModel::moduleBusinessSingleResourcesUpdate(
                ResourcesModel::MODULE_TYPE_COLLEGE,
                ResourcesModel::BUSINESS_COLLEGE_COURSES,
                'failLetter',
                $this->collegeTrainingOrderModel->id,
                $failLetterUrls
            );
        }

        $this->collegeTrainingOrderModel->userRel->each(function ($item) use ($users) {
            $item->comment          = $users[$item->userId]['comment'] ?? "";
            $item->practiceScore    = $users[$item->userId]['practiceScore'] ?? 0;
            $item->practiceResult   = $item->practiceScore >= CollegeInputService::PRACTICE_SUCCESS_RATE ? CollegeTrainingOrderUserModel::RESULT_OK : CollegeTrainingOrderUserModel::RESULT_FAIL;

            if ($item->practiceResult == CollegeTrainingOrderUserModel::RESULT_OK && $item->examResult == CollegeTrainingOrderUserModel::RESULT_OK) {
                $item->finalResult = CollegeTrainingOrderUserModel::RESULT_OK;
            } else {
                $item->finalResult = CollegeTrainingOrderUserModel::RESULT_FAIL;
            }

            $item->save();

            ResourcesModel::moduleBusinessSingleResourcesUpdate(
                ResourcesModel::MODULE_TYPE_COLLEGE,
                ResourcesModel::BUSINESS_COLLEGE_COURSES,
                'practiceCheckUrls',
                $item->id,
                $users[$item->userId]['practiceCheckUrls']
            );
        });


        $successNum = $this->collegeTrainingOrderModel->userRel
            ->where('finalResult', CollegeTrainingOrderUserModel::RESULT_OK)->count();
        $totalNum   = $this->collegeTrainingOrderModel->userRel->count();

        // 所有人均通过 理论&实操考试 - result更新
        if ($successNum >= 2 && $totalNum >= 2) {
            $this->collegeTrainingOrderModel->result = CollegeTrainingOrderModel::RESULT_SUCCESS;
        } else {
            $this->collegeTrainingOrderModel->result = CollegeTrainingOrderModel::RESULT_FAIL;
        }

        $this->collegeTrainingOrderModel->portrait  = $portrait;
        $this->collegeTrainingOrderModel->status    = CollegeTrainingOrderModel::STATUS_FINISH;
        $this->collegeTrainingOrderModel->save();

        CollegeTrainingOrderLogModel::add($this->collegeTrainingOrderModel->id, "实操上传", $currentUid);

        DB::commit();

        // 工服标签更新
        (new ShopTagsService('', $this->collegeTrainingOrderModel->studentShopId))->updateWorkClothes();

        $successNum = $this->collegeTrainingOrderModel->userRel
            ->where('finalResult', CollegeTrainingOrderUserModel::RESULT_OK)->count();
        $totalNum   = $this->collegeTrainingOrderModel->userRel->count();

        // 至少2名学员合格
        if ($successNum >= 2 && $totalNum >= 2) {

            //获得门店信息
            $shopInfo  = (new RmsShopApi())->getShopByIds([$this->collegeTrainingOrderModel->studentShopId],
                    ['shopCode'])['data']['shopList'][0] ?? [];
            $trainFile = QualificationImageService::trainComplete('KF' . ($shopInfo['shopCode'] ?? '****'),
                (int)optional($this->collegeTrainingOrderModel->planRel)->planStartTime,
                (int)optional($this->collegeTrainingOrderModel->planRel)->planEndTime, time());

            ResourcesModel::moduleBusinessSingleResourcesUpdate(
                ResourcesModel::MODULE_TYPE_COLLEGE,
                ResourcesModel::BUSINESS_COLLEGE_COURSES,
                'trainCompleteImg',
                $this->collegeTrainingOrderModel->id,
                [$trainFile['path'] ?? '']
            );
        }

        $this->collegeTrainingOrderModel->userRel->where('examResult', CollegeTrainingOrderUserModel::RESULT_INIT)
                                                 ->each(function ($item) {

                                                     // 把所有没提交的考卷都关了
                                                     dispatch((new AutoCloseExam($item->cruiseOrderId, false)));
                                                 });
        //商学院培训阶段-在「商家商学院培训」完成之后，进行推送 评价消息
        $this->collegeTrainingOrderModel->userRel
            ->each(function ($item) use ($users) {
                NotifyService::notify($this->collegeTrainingOrderModel->orderNo, AppraiseModel::TYPE_OPENSHOP_COLLEGE, $item->userId, $this->collegeTrainingOrderModel->studentShopId);
            });

        (new ShopTagsService('', $this->collegeTrainingOrderModel->studentShopId))
            ->updateSchoolTag(); // 生成商学院培训标签


        dispatch((new FinishTrainingOrderJob($this->collegeTrainingOrderModel->id)));
    }

    /**
     * 新增参训人员
     * @param int $userId
     * @return void
     */
    public function userAdd(int $userId, int $currentUid): void
    {
        $check = $this->collegeTrainingOrderModel->userRel->where('userId', $userId)->count();
        if ($check) {
            self::throwErr("培训订单中，已存在该用户");
        }

        // 判断是否在门店中
        $userIds = collect((new RmsShopApi())->getShopStaffListByShopId($this->collegeTrainingOrderModel->studentShopId)['data']['list'] ?? [])
            ->pluck('id')
            ->toArray();
        if (!in_array($userId, $userIds)) {
            self::throwErr("此用户不属于该门店");
        }

        DB::beginTransaction();

        // add
        CollegeTrainingOrderUserModel::init($userId, $this->collegeTrainingOrderModel->id);

        // 判断新增试卷
        if (in_array($this->collegeTrainingOrderModel->status,
            [CollegeTrainingOrderModel::STATUS_ING, CollegeTrainingOrderModel::STATUS_WAIT_UPLOAD])) {

            // 重新加载userRel关系
            $this->collegeTrainingOrderModel->load('userRel');
            CollegeExamService::initExam($this->collegeTrainingOrderModel);
        }

        $this->collegeTrainingOrderModel->actualNum = DB::raw('actualNum+1');
        $this->collegeTrainingOrderModel->save();

        //添加日志
        $username = RmsUserService::getRmsUserInfoByUserIds([$userId])['data'][0]['username'] ?? '';
        CollegeTrainingOrderLogModel::add($this->collegeTrainingOrderModel->id, "新增实际参训人员 - {$username}", $currentUid);

        DB::commit();
    }

    /**
     * 移除参训人员
     * @param int $userId
     * @return void
     */
    public function userRemove(int $userId, int $currentUid): void
    {
        if ($this->collegeTrainingOrderModel->status == CollegeTrainingOrderModel::STATUS_FINISH) {
            self::throwErr("已完成的订单无法移除人员");
        }

        if ($this->collegeTrainingOrderModel->status == CollegeTrainingOrderModel::STATUS_CLOSE) {
            self::throwErr("已关闭的订单无法移除人员");
        }

        $orderUser = CollegeTrainingOrderUserModel::query()
                                                  ->where('userId', $userId)
                                                  ->where('trainingOrderId', $this->collegeTrainingOrderModel->id)
                                                  ->first();
        if (!$orderUser) {
            self::throwErr("培训订单中，不存在该用户");
        }

        DB::beginTransaction();

        // 人移除，试卷也关了
        $orderUser->isDeleted = 1;
        $orderUser->save();

        CruiseOrderModel::query()
                        ->where('id', $orderUser->cruiseOrderId)
                        ->update(['status' => CruiseOrderModel::STATUS_CLOSED]);

        // 有其他完成试卷的人
        $finishNum = CollegeTrainingOrderUserModel::query()
                                                  ->where('trainingOrderId', $this->collegeTrainingOrderModel->id)
                                                  ->whereIn('examResult', [
                                                      CollegeTrainingOrderUserModel::RESULT_OK,
                                                      CollegeTrainingOrderUserModel::RESULT_FAIL
                                                  ])
                                                  ->count();
        if ($finishNum > 0) {

            $checkOther = CollegeTrainingOrderUserModel::query()
                                                       ->where('trainingOrderId', $this->collegeTrainingOrderModel->id)
                                                       ->where('examResult', CollegeTrainingOrderUserModel::RESULT_INIT)
                                                       ->count();
            if ($checkOther == 0) {

                // 其他所有人都考完 - 改成待上传
                $this->collegeTrainingOrderModel->status = CollegeTrainingOrderModel::STATUS_WAIT_UPLOAD;
            }
        }


        $this->collegeTrainingOrderModel->actualNum = DB::raw('actualNum-1');
        $this->collegeTrainingOrderModel->save();

        // 没有异常的人，改成初始化
        $this->collegeTrainingOrderModel->resetResult();

        //添加日志
        $username = RmsUserService::getRmsUserInfoByUserIds([$userId])['data'][0]['username'] ?? '';
        CollegeTrainingOrderLogModel::add($this->collegeTrainingOrderModel->id, "移除实际参训人员 - {$username}", $currentUid);

        DB::commit();

        if ($this->collegeTrainingOrderModel->status == CollegeTrainingOrderModel::STATUS_WAIT_UPLOAD) {

            // 工服标签更新
            (new ShopTagsService('', $this->collegeTrainingOrderModel->studentShopId))->updateWorkClothes();
        }
    }

    /**
     * 添加订单
     * @param int $currentUid
     * @param int $shopId
     * @return void
     */
    public function orderAdd(int $currentUid, int $shopId, bool $sendFsToMerchant = true): int
    {
        // 是否有未完成的培训订单
        $check = CollegeTrainingOrderModel::query()
                                          ->where('studentShopId', $shopId)
                                          ->whereNotIn('status', [
                                              CollegeTrainingOrderModel::STATUS_FINISH,
                                              CollegeTrainingOrderModel::STATUS_CLOSE
                                          ])
                                          ->count();
        if ($check) {
            self::throwErr("该参训门店有未完成订单，请完成后再新建！");
        }

        DB::beginTransaction();

        // 生成商学院培训流程
        $collegeTrainingOrderModel = CollegeTrainingOrderModel::init($shopId);

        // 添加日志
        if ($currentUid) {
            $content = '后台手动下单';
        } else {
            $content = '自动下单';
        }

        CollegeTrainingOrderLogModel::add($collegeTrainingOrderModel->id, $content, $currentUid);

        DB::commit();

        if ($sendFsToMerchant) {

            $mainProcessId  = OpenShopMainProcessModel::query()
                                                      ->where('shopId', $shopId)
                                                      ->orderByDesc('id')
                                                      ->value('id') ?? 0;
            $merchantUserId = OpenShopSignOrderModel::query()
                                                    ->where('mainProcessId', $mainProcessId)
                                                    ->orderByDesc('id')
                                                    ->value('merchantUserId') ?? 0;

            if ($merchantUserId) {

                // 向商家发送报名消息
                $notify = SystemNotifyService::save(
                    false,
                    '你的新店培训单已生成，请注意查收！',
                    SystemNotifyCenterModel::NOTIFY_TYPE_3,
                    SystemNotifyCenterModel::NOTIFY_TARGET_1,
                    '',
                    '你的新店培训单已生成，请注意查收！',
                    config('webUrl.notify_web_cdn_url') . '#/pages/merchant-school/train/list',
                    SystemNotifyCenterModel::METHOD_TYPE_AUTOMATIC,
                    "亲爱的夸父伙伴，您的新店培训单已生成请点击确认报名信息。",
                    '',
                    SystemNotifyCenterModel::IS_POPUP_ON,
                    1,
                    $shopId
                );
                SystemNotifyService::recordLog($notify, '创建消息');
                SystemNotifyService::preSend($notify->id, [$merchantUserId]);
            }
        }

        return $collegeTrainingOrderModel->id;
    }

    /**
     * 补考
     * @param string $examNo
     * @return void
     */
    public function orderRepair(string $examNo, int $currentUid): void
    {
        $orderUserModel = CollegeTrainingOrderUserModel::query()
                                                       ->where('trainingOrderId', $this->collegeTrainingOrderModel->id)
                                                       ->where('examNo', $examNo)
                                                       ->orderByDesc('id')
                                                       ->first();
        if (!$orderUserModel) {
            self::throwErr("不存在的examNo: {$examNo}/{$this->collegeTrainingOrderModel->id}");
        }

        $userName = RmsUserService::getRmsUserInfoByUserIds([$orderUserModel->userId])['data'][0]['username'] ?? '';

        DB::beginTransaction();

        // add
        CollegeTrainingOrderUserModel::init($orderUserModel->userId, $this->collegeTrainingOrderModel->id);

        // 新增试卷
        CollegeExamService::initExam($this->collegeTrainingOrderModel);

        $orderUserModel->isHistory = 1;
        $orderUserModel->save();

        CollegeTrainingOrderLogModel::add($this->collegeTrainingOrderModel->id, "新增补考：" . $userName, $currentUid);

        DB::commit();
    }

    /**
     * 修改参训门店
     * @param int $teacherShopId
     * @return void
     */
    public function editTeacherShop(int $teacherShopId, int $currentUid): void
    {
        if ($this->collegeTrainingOrderModel->status == CollegeTrainingOrderModel::STATUS_FINISH) {
            self::throwErr("已完成的订单无法修改");
        }

        if ($this->collegeTrainingOrderModel->status == CollegeTrainingOrderModel::STATUS_CLOSE) {
            self::throwErr("已关闭的订单无法修改");
        }

        $oldTeacherShopId = $this->collegeTrainingOrderModel->teacherShopId;

        $shops = collect((new RmsShopApi())->getShopByIds([
                $oldTeacherShopId,
                $teacherShopId
            ])['data']['shopList'] ?? [])->keyBy('id');

        $oldTeacherName     = $shops[$oldTeacherShopId]['name'] ?? '';
        $oldTeacherShopCode = $shops[$oldTeacherShopId]['shopCode'] ?? '';

        $newTeacherName = $shops[$teacherShopId]['name'] ?? '';
        $newTeacherCode = $shops[$teacherShopId]['shopCode'] ?? '';

        DB::beginTransaction();

        $this->collegeTrainingOrderModel->teacherShopId = $teacherShopId;
        $this->collegeTrainingOrderModel->save();

        CollegeTrainingOrderLogModel::add($this->collegeTrainingOrderModel->id,
            "修改参训门店 {$oldTeacherShopCode}{$oldTeacherName} => {$newTeacherCode}{$newTeacherName}", $currentUid);

        DB::commit();
    }
}
